{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3f159fb4",
   "metadata": {},
   "source": [
    "# 🚶🏻‍♂️ Getting Started\n",
    "\n",
    "Here you will learn how to use the fastembed package to embed your data into a vector space. The package is designed to be easy to use and fast. It is built on top of the [ONNX](https://onnx.ai/) standard, which allows for fast inference on a variety of hardware (called Runtimes in ONNX). \n",
    "\n",
    "## Quick Start\n",
    "\n",
    "The fastembed package is designed to be easy to use. We'll be using `TextEmbedding` class. It takes a list of strings as input and returns a generator of vectors.\n",
    "\n",
    "> 💡 You can learn more about generators from [Python Wiki](https://wiki.python.org/moin/Generators)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ada95c6a",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -Uqq fastembed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b61c6552",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "890cc3b969354eec8d149d143e301a7a",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Fetching 9 files:   0%|          | 0/9 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The model BAAI/bge-small-en-v1.5 is ready to use.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "384"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "from fastembed import TextEmbedding\n",
    "\n",
    "\n",
    "# Example list of documents\n",
    "documents: list[str] = [\n",
    "    \"This is built to be faster and lighter than other embedding libraries e.g. Transformers, Sentence-Transformers, etc.\",\n",
    "    \"fastembed is supported by and maintained by Qdrant.\",\n",
    "]\n",
    "\n",
    "# This will trigger the model download and initialization\n",
    "embedding_model = TextEmbedding()\n",
    "print(\"The model BAAI/bge-small-en-v1.5 is ready to use.\")\n",
    "\n",
    "embeddings_generator = embedding_model.embed(documents)\n",
    "embeddings_list = list(embeddings_generator)\n",
    "len(embeddings_list[0])  # Vector of 384 dimensions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d772190b",
   "metadata": {},
   "source": [
    "> 💡 **Why do we use generators?**\n",
    "> \n",
    "> We use them to save memory mostly. Instead of loading all the vectors into memory, we can load them one by one. This is useful when you have a large dataset and you don't want to load all the vectors at once."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8a225cb8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Document: This is built to be faster and lighter than other embedding libraries e.g. Transformers, Sentence-Transformers, etc.\n",
      "Vector of type: <class 'numpy.ndarray'> with shape: (384,)\n",
      "Document: fastembed is supported by and maintained by Qdrant.\n",
      "Vector of type: <class 'numpy.ndarray'> with shape: (384,)\n"
     ]
    }
   ],
   "source": [
    "embeddings_generator = embedding_model.embed(documents)\n",
    "\n",
    "for doc, vector in zip(documents, embeddings_generator):\n",
    "    print(\"Document:\", doc)\n",
    "    print(f\"Vector of type: {type(vector)} with shape: {vector.shape}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "769a1be9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 384)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "embeddings_list = np.array(list(embedding_model.embed(documents)))\n",
    "embeddings_list.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c49ae50",
   "metadata": {},
   "source": [
    "We're using [BAAI/bge-small-en-v1.5](https://huggingface.co/BAAI/bge-small-en-v1.5) a state of the art Flag Embedding model. The model does better than OpenAI text-embedding-ada-002. We've made it even faster by converting it to ONNX format and quantizing the model for you.\n",
    "\n",
    "#### Format of the Document List\n",
    "\n",
    "1. List of Strings: Your documents must be in a list, and each document must be a string\n",
    "2. For Retrieval Tasks with our default: If you're working with queries and passages, you can add special labels to them:\n",
    "- **Queries**: Add \"query:\" at the beginning of each query string\n",
    "- **Passages**: Add \"passage:\" at the beginning of each passage string\n",
    "\n",
    "## Beyond the default model\n",
    "\n",
    "The default model is built for speed and efficiency. If you need a more accurate model, you can use the `TextEmbedding` class to load any model from our list of available models. You can find the list of available models using `TextEmbedding.list_supported_models()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2e9c8766",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9470ec542f3c4400a42452c2489a1abc",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Fetching 8 files:   0%|          | 0/8 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "multilingual_large_model = TextEmbedding(\"intfloat/multilingual-e5-large\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "a9e70f0e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 1024)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array(\n",
    "    list(multilingual_large_model.embed([\"Hello, world!\", \"你好世界\", \"¡Hola Mundo!\", \"नमस्ते!\"]))\n",
    ").shape  # Vector of 1024 dimensions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64fe20ed",
   "metadata": {},
   "source": [
    "Next: Checkout how to use FastEmbed with Qdrant for similarity search: [FastEmbed with Qdrant](https://qdrant.github.io/fastembed/examples/Usage_With_Qdrant/)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
